package top.went.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.went.db.dao.*;
import top.went.exception.ServiceException;
import top.went.pojo.*;
import top.went.utils.Md5;
import top.went.vo.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Service
@Transactional(value = "transactionManager", rollbackFor = ServiceException.class)
public class GrantService {

    private final UserDao userDao;
    private final DeptDao deptDao;
    private final RoleDao roleDao;
    private final FunctionDao functionDao;
    private final FcTypeDao fcTypeDao;
    private final RoleFcDao roleFcDao;
    private final UserRoleDao userRoleDao;

    @Autowired
    public GrantService(UserDao userDao, DeptDao deptDao, RoleDao roleDao, FunctionDao functionDao, FcTypeDao fcTypeDao, RoleFcDao roleFcDao, UserRoleDao userRoleDao) {
        this.userDao = userDao;
        this.deptDao = deptDao;
        this.roleDao = roleDao;
        this.functionDao = functionDao;
        this.fcTypeDao = fcTypeDao;
        this.roleFcDao = roleFcDao;
        this.userRoleDao = userRoleDao;
    }

    private static final Long LOGIN_ID = 1L;

    /**
     * 分页显示所有角色
     *
     * @param pageNumber
     * @param pageSize
     * @return
     * @throws ServiceException
     */
    public PageEntity<RoleEntity> queryAllRoles(Integer pageNumber, Integer pageSize)
            throws ServiceException {
        try {
            PageRequest pageRequest = new PageRequest(pageNumber, pageSize);
            List<RoleEntity> list = roleDao.findAllByRoleIsDelOrderByRoleIdDesc(0L, pageRequest);
            return new PageEntity(roleDao.countAllByRoleIsDel(0L), list);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("查找所有角色错误");
        }
    }

    /**
     * 添加新角色
     *
     * @param roleName
     * @return
     * @throws ServiceException
     */
    public boolean addRole(String roleName) throws ServiceException {
        try {
            RoleEntity roleEntity = new RoleEntity();
            roleEntity.setRoleName(roleName);
            roleEntity.setRoleIsDel(0L);
            roleDao.save(roleEntity);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("添加角色错误");
        }
    }

    /**
     * 修改角色
     *
     * @param roleId
     * @param roleName
     * @return
     * @throws ServiceException
     */
    public boolean modifyRole(Long roleId, String roleName) throws ServiceException {
        try {
            RoleEntity roleEntity = roleDao.findRoleEntityByRoleIdAndAndRoleIsDel(roleId, 0L);
            roleEntity.setRoleName(roleName);
            roleDao.save(roleEntity);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("修改角色错误");
        }
    }

    /**
     * 加载角色
     *
     * @param roleId
     * @return
     * @throws ServiceException
     */
    public RoleEntity queryRole(Long roleId) throws ServiceException {
        try {
            return roleDao.findRoleEntityByRoleIdAndAndRoleIsDel(roleId, 0L);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("加载角色");
        }
    }

    /**
     * 删除角色
     *
     * @param roleId
     * @return
     * @throws ServiceException
     */
    public boolean deleteRole(Long roleId) throws ServiceException {
        try {
            RoleEntity roleEntity = roleDao.findRoleEntityByRoleIdAndAndRoleIsDel(roleId, 0L);
            roleEntity.setRoleIsDel(1L);
            roleDao.save(roleEntity);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("删除角色错误");
        }
    }

    /**
     * 查找出指定角色的所有功能列表
     *
     * @param roleId
     * @return
     * @throws ServiceException
     */
    public List<FunctionNode> getFunctionNodes(Long roleId) throws ServiceException {
        try {
            List<FunctionNode> nodes = new ArrayList<FunctionNode>();
            //第一步：获取所有的功能分组
            List<FcTypeEntity> typeList = fcTypeDao.queryAll();
            //第二步：找出每一个功能分组中的功能列表
            if (typeList != null) {
                for (FcTypeEntity type : typeList) {
                    List<Object[]> objArrList = roleDao.queryFunctionsByRoleId(roleId, type.getFcTypeId());
                    List<FunctionsEntity> functionsEntities = new ArrayList<FunctionsEntity>();
                    if (objArrList != null) {
                        for (Object[] objArr : objArrList) {
                            functionsEntities.add(objArr2Function(objArr));
                        }
                    }
                    //构造FunctionNode对象
                    FunctionNode node = new FunctionNode();
                    node.setFcTypeId(type.getFcTypeId());
                    node.setFcTypeName(type.getFcTypeName());
                    node.setFcs(functionsEntities);
                    nodes.add(node);
                }
            }
            return nodes;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("查找功能列表错误");
        }
    }

    /**
     * 查找出指定角色的所有用户列表
     *
     * @param roleId
     * @return
     * @throws ServiceException
     */
    public List<DeptVo> getUserNodes(Long roleId) throws ServiceException {
        try {
            List<DeptVo> nodes = new ArrayList<DeptVo>();
            List<DeptEntity> deptList = deptDao.findAllDept();
            if (deptList != null) {
                for (DeptEntity dept : deptList) {
                    List<Object[]> objArrList = roleDao.queryUsersByRoleId(roleId, dept.getDeptId());
                    List<UserVo> userEntities = new ArrayList<UserVo>();
                    if (objArrList != null) {
                        for (Object[] objArr : objArrList) {
                            userEntities.add(objArr2User(objArr));
                        }
                    }
                    DeptVo node = new DeptVo();
                    node.setDeptId(dept.getDeptId());
                    node.setDeptName(dept.getDeptName());
                    node.setList(userEntities);
                    nodes.add(node);
                }
            }
            return nodes;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("查找用户列表错误");
        }
    }

    /**
     * 查找出指定用户的所有角色列表
     *
     * @param userId
     * @return
     * @throws ServiceException
     */
    public UserRoleNode getRoleNodes(Long userId) throws ServiceException {
        try {
            List<Object[]> objArrList = userDao.queryRolesByUserId(userId);
            List<RoleEntity> roleEntities = new ArrayList<RoleEntity>();
            if (objArrList != null) {
                for (Object[] objArr : objArrList) {
                    roleEntities.add(objArr2Role(objArr));
                }
            }
            UserRoleNode node = new UserRoleNode();
            node.setUserId(userId);
            node.setList(roleEntities);
            return node;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("查找角色列表错误");
        }
    }

    /**
     * 将Object[]转换成Function对象
     *
     * @param objArr
     * @return
     */
    private FunctionsEntity objArr2Function(Object[] objArr) {
        FunctionVo functionVo = new FunctionVo();
        functionVo.setFcId(((BigDecimal) objArr[0]).longValue());
        functionVo.setFcName((String) objArr[1]);
        functionVo.setSelected(((BigDecimal) objArr[2]).intValue() == 1);
        return functionVo;
    }

    /**
     * 将Object[]转换成User对象
     *
     * @param objArr
     * @return
     */
    private UserVo objArr2User(Object[] objArr) {
        UserPassword userVo = new UserPassword();
        userVo.setUserId(((BigDecimal) objArr[0]).longValue());
        userVo.setUserName((String) objArr[1]);
        userVo.setSelected(((BigDecimal) objArr[2]).intValue() == 1);
        return userVo;
    }

    /**
     * 将Object[]转换成Role对象
     *
     * @param objArr
     * @return
     */
    private RoleEntity objArr2Role(Object[] objArr) {
        UserRoleVo userRoleVo = new UserRoleVo();
        userRoleVo.setRoleId(((BigDecimal) objArr[0]).longValue());
        userRoleVo.setRoleName((String) objArr[1]);
        userRoleVo.setSelected(((BigDecimal) objArr[2]).intValue() == 1);
        return userRoleVo;
    }

    /**
     * 给指定的角色授权
     *
     * @param ids
     * @return
     * @throws ServiceException
     */
    public boolean grantFcToRole(RoleIdAndFcIds ids) throws ServiceException {
        try {
            List<RoleFcEntity> rcs = roleFcDao.queryAllByRoleIdAndRoleFcIsDel(ids.getRoleId(), 0L);
            for (RoleFcEntity rc : rcs) {
                rc.setRoleFcIsDel(1L);
                roleFcDao.save(rc);
            }
            if (ids.getFcIds() != null) {
                RoleEntity role = roleDao.findRoleEntityByRoleIdAndAndRoleIsDel(ids.getRoleId(), 0L);
                //为角色添加新的功能
                for (Long funId : ids.getFcIds()) {
                    RoleFcEntity roleFcEntity = new RoleFcEntity();
                    roleFcEntity.setTbRoleByRoleId(role);
                    roleFcEntity.setRoleFcIsDel(0L);
                    roleFcEntity.setTbFunctionsByFcId(functionDao.findOne(funId));
                    roleFcDao.save(roleFcEntity);
                }
                return true;
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("角色授权错误");
        }
    }

    /**
     * 给指定角色分配用户
     *
     * @param ids
     * @return
     * @throws ServiceException
     */
    public boolean grantUserToRole(RoleIdAndUserIds ids) throws ServiceException {
        try {
            List<UserRoleEntity> urs = userRoleDao.queryAllByRoleIdAndUserRoleIsDel(ids.getRoleId(), 0L);
            for (UserRoleEntity ur : urs) {
                ur.setUserRoleIsDel(1L);
                userRoleDao.save(ur);
            }
            if (ids.getUserIds() != null) {
                RoleEntity role = roleDao.findRoleEntityByRoleIdAndAndRoleIsDel(ids.getRoleId(), 0L);
                for (Long userId : ids.getUserIds()) {
                    UserRoleEntity userRoleEntity = new UserRoleEntity();
                    userRoleEntity.setTbRoleByRoleId(role);
                    userRoleEntity.setUserRoleIsDel(0L);
                    userRoleEntity.setTbUserByUserId(userDao.findUserByOne(0L, userId));
                    userRoleDao.save(userRoleEntity);
                }
                return true;
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("角色分配用户失败");
        }
    }

    /**
     * 用户分配角色
     *
     * @param userId
     * @param ids
     * @return
     * @throws ServiceException
     */
    public boolean grantRoleToUser(Long userId, int[] ids) throws ServiceException {
        try {
            List<UserRoleEntity> urs = userRoleDao.queryAllByUserIdAndUserRoleIsDel(userId, 0L);
            for (UserRoleEntity ur : urs) {
                ur.setUserRoleIsDel(1L);
                userRoleDao.save(ur);
            }
            System.out.println("删掉了");
            if (ids.length > 0) {
                UserEntity userEntity = userDao.findUserByOne(0L, userId);
                for (int id : ids) {
                    UserRoleEntity userRoleEntity = new UserRoleEntity();
                    userRoleEntity.setUserRoleIsDel(0L);
                    userRoleEntity.setTbUserByUserId(userEntity);
                    userRoleEntity.setTbRoleByRoleId(roleDao.findRoleEntityByRoleIdAndAndRoleIsDel((long) id, 0L));
                    userRoleDao.save(userRoleEntity);
                    System.out.println("添加");
                }
                return true;
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("用户分配角色失败");
        }
    }

    /**
     * 登陆权限验证
     *
     * @param user
     * @return
     */
    public boolean login(UserEntity user) throws ServiceException {
        try {
//            UserEntity user = userDao.loginByPassword(0L, name, Md5.encode(password));
//            if (user != null) {
            //如果用户名和密码没有错误，再判断该用户是否有“登陆”权限
            List<BigDecimal> funIds = userDao.queryFcIdByUserId(user.getUserId());
            System.out.println("功能列表" + funIds);
            System.out.println("登录：" + LOGIN_ID.getClass().getName());
            if(funIds!=null){
                for (int i = 0; i < funIds.size(); i++) {
                    if (funIds.get(i).longValue() == LOGIN_ID.longValue()) {
                        return true;
                    }
                }
            }
            return false;
            //            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("登录失败");
        }
    }

    /**
     * 根据用户id获取该用户的所有功能id集合
     *
     * @param userId
     * @return
     */
    public List<BigDecimal> queryFunctionIdsByUserId(Long userId) throws ServiceException {
        try {
            return userDao.queryFcIdByUserId(userId);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("操作错误");
        }
    }

    /**
     * 角色名称模糊查询角色
     *
     * @param roleName
     * @param pageNumber
     * @param pageSize
     * @return
     * @throws ServiceException
     */
    public PageEntity<RoleEntity> queryRolesByRoleNameLike(String roleName, Integer pageNumber, Integer pageSize) throws ServiceException {
        try {
            PageRequest pageRequest = new PageRequest(pageNumber, pageSize);
            List<RoleEntity> list = roleDao.findAllByRoleNameLikeAndRoleIsDel("%" + roleName + "%", 0L, pageRequest);
            PageEntity pageEntity = new PageEntity(roleDao.countAllByRoleNameLikeAndRoleIsDel("%" + roleName + "%", 0L), list);
            return pageEntity;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("模糊查询错误");
        }
    }
}
